# 一、分析目的
"""
客户流失分析的主要目的是通过分析用户特征，寻找对用户流失影响较大的用户特征。
根据电商领域的业务知识，提出产品/平台的运营建议，以提高用户粘性，降低用户流失率。
"""
# 导入数据相关包
import warnings

import pandas as pd
import seaborn as sns
from matplotlib import pyplot as plt

"""
1、流失用户有哪些属性？
2、尝试找到合适的模型预测流失用户。
3、针对性给出增加用户黏性、预防流失的建议。
"""

# 忽略警告提示
warnings.filterwarnings('ignore')
# 用黑体显示中文

plt.rcParams['font.sans-serif'] = ['SimHei']

# 加载数据集
df = pd.read_excel('E:\桌面\大四\毕设\Project Dataset.xlsx', sheet_name='E Comm')
df.shape

# 查看数据信息
df.head()

# 数据集描述
df.info()
# 根据上面打印的结果，我们发现数据总共有5630行，共有19个变量。


# 二、数据清洗
# 1、判断某指标的缺失值
missingTotal = df.isnull().sum()
missingExist = missingTotal[missingTotal > 0]
missingExist = missingExist.sort_values(ascending=False)
print(missingTotal)
print(missingExist)

# 2、处理缺失值
# 1）使用中位数填充具有明显离群值和偏态分布的数据
fig, axes = plt.subplots(1, 3, figsize=(18, 6))
plt.title('全部用户的任期直方图')
sns.distplot(df['Tenure'].dropna(), ax=axes[0])
plt.title('流失用户的任期直方图')
sns.distplot(df[df['Churn'] == 1]['Tenure'].dropna(), ax=axes[1])
plt.title('留存用户的任期直方图')
sns.distplot(df[df['Churn'] == 0]['Tenure'].dropna(), ax=axes[2])
plt.show()

df['Tenure'] = df['Tenure'].fillna(df['Tenure'].median())  # 数据有明显的离群值，切呈偏态分布
df['WarehouseToHome'] = df['WarehouseToHome'].fillna(df['WarehouseToHome'].median())  # 数据有明显离群值
df['OrderAmountHikeFromlastYear'] = df['OrderAmountHikeFromlastYear'].fillna(
    df['OrderAmountHikeFromlastYear'].median())  # 数据呈偏态分布
df['CouponUsed'] = df['CouponUsed'].fillna(df['CouponUsed'].median())  # 数据呈偏态分布
df['DaySinceLastOrder'] = df['DaySinceLastOrder'].fillna(df['DaySinceLastOrder'].median())  # 数据有明显离群值，且呈偏态分布

# 2)使用均值填充变量值较好地集中在均值周围的数据
fig, axes = plt.subplots(1, 3, figsize=(18, 6))
plt.title('全部用户的app花费时间直方图')
sns.distplot(df['HourSpendOnApp'].dropna(), ax=axes[0])
plt.title('流失用户的app花费时间直方图')
sns.distplot(df[df['Churn'] == 1]['HourSpendOnApp'].dropna(), ax=axes[1])
plt.title('留存用户的app花费时间直方图')
sns.distplot(df[df['Churn'] == 0]['HourSpendOnApp'].dropna(), ax=axes[2])
plt.show()

df['HourSpendOnApp'] = df['HourSpendOnApp'].fillna(df['HourSpendOnApp'].mean())

# 3)使用特殊值填充缺失值  数据的空值代表上月无订单，填充为0
df['OrderCount'] = df['OrderCount'].fillna('0')

# 4)再次判断缺失值
missingTotal = df.isnull().sum()
missingExist = missingTotal[missingTotal > 0]
missingExist = missingExist.sort_values(ascending=False)
print(missingTotal)
print(missingExist)
# 此时数据中已经无缺失值


# 3、数据一致化
# 目的是对数据进行相关处理，以便后续计算分析。

# 将 Churn 列转换为整数类型
df['Churn'] = df['Churn'].astype(int)

# 将 tenure 列的数据类型转换为整数
df['Tenure'] = df['Tenure'].astype(int)

# 将 ageGroup 列的数据类型转换为整数
df['AgeGroup'] = df['AgeGroup'].astype(int)

# 将性别属性转换为 0 和 1，女性为 0，男性为 1
# df['Gender'] = pd.factorize(df['Gender'])[0]

# 将 HourSpendOnApp 列的数据类型转换为浮点数
df['HourSpendOnApp'] = df['HourSpendOnApp'].astype(float)

# 将 OrderCount 列的数据类型转换为整数
df['OrderCount'] = df['OrderCount'].astype(int)

# 将 OrderAmountHikeFromlastYear 列的数据类型转换为浮点数
df['OrderAmountHikeFromlastYear'] = df['OrderAmountHikeFromlastYear'].astype(float)

# 将 DaySinceLastOrder 列的数据类型转换为整数
df['DaySinceLastOrder'] = df['DaySinceLastOrder'].astype(int)

# 将 PreferredOrderCat 列的数据类型转换为字符串
df['PreferedOrderCat'] = df['PreferedOrderCat'].astype(str)

# 将 NumberOfStreamerFollowed 列的数据类型转换为整数
df['NumberOfStreamerFollowed'] = df['NumberOfStreamerFollowed'].astype(int)

# 将 SatisfactionScore 列的数据类型转换为浮点数
df['SatisfactionScore'] = df['SatisfactionScore'].astype(float)

# 将 Complain 列的数据类型转换为整数
df['Complain'] = df['Complain'].astype(int)

# 将 DiscountAmount 列的数据类型转换为浮点数
df['DiscountAmount'] = df['DiscountAmount'].astype(float)

# 将 DiscountAmount 列的数据类型转换为浮点数
df['DiscountAmount'] = df['DiscountAmount'].astype(float)
